package com.zl.ssh.tunnel;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class SSHChunnel {
    @Autowired
    private SSHConfig sshConfig;
    private JSch jsch;
    private Session session = null;
    private Channel channel;

    /**
     * 创建SSH隧道
     */
    public void createChunnel()
    {
        try {
            jsch = new JSch();

            session = jsch.getSession(sshConfig.getUser(),sshConfig.getHost() ,sshConfig.getPort() );
            session.setPassword(sshConfig.getPassword());
            // 设置不进行主机密钥检查
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);

            // 建立SSH连接
            session.connect();

        } catch (JSchException e) {
            throw new RuntimeException(e);
        }

    }

    public void closeChunnel()
    {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
    }

    /**
     * 建立端口转发服务
     */
    public void startChunnel() throws JSchException {
        // 设置端口转发
        if (sshConfig.getPortForwardingList() != null) {
            for (PortForwarding portForwarding : sshConfig.getPortForwardingList()) {
                int assignedLocalPort = session.setPortForwardingL(portForwarding.getLocalPort(), portForwarding.getRemoteHost(), portForwarding.getRemotePort());
                System.out.println("Local port " + assignedLocalPort + " is now forwarding to " + portForwarding.getRemoteHost() + ":" + portForwarding.getRemotePort());
            }
        }

        // 保持连接打开
        channel = session.openChannel("shell");
        channel.connect();
    }

    /**
     * 在Bean初始化完成后启动SSH隧道
     */
    @PostConstruct
    public void init() {
        if(sshConfig.isEnabled())
        {
            try {
                createChunnel();
                startChunnel();
            } catch (JSchException e) {
                throw new RuntimeException("Failed to start SSH tunnel", e);
            }
        }

    }

    /**
     * 定期检查SSH连接状态并重连
     */
    @Scheduled(fixedRate = 10000) // 每10秒检查一次
    public void checkAndReconnect() {
        if (sshConfig.isEnabled())
        {
            if (session == null || !session.isConnected()) {
                System.out.println("SSH tunnel is disconnected, attempting to reconnect...");
                try {
                    closeChunnel(); // 先关闭旧的连接
                    createChunnel();
                    startChunnel();
                    System.out.println("SSH tunnel reconnected successfully.");
                } catch (JSchException e) {
                    System.err.println("Failed to reconnect SSH tunnel: " + e.getMessage());
                }
            }
        }
    }

    /**
     * 在Bean销毁前关闭SSH隧道并取消定时任务
     */
    @PreDestroy
    public void destroy() {
        if (session != null && session.isConnected()) {
            closeChunnel();
            System.out.println("SSH tunnel closed on application shutdown.");
        }
        sshConfig.setIsEnabled(false);
    }

}
